package com.ludomancy.gamelib.ui;

import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;

import com.ludomancy.gamelib.Widget;

public class ScrollBarWidget extends Widget
{
	private int maxValue;
	private int currentValue;
	private int pageSize;
	private int mouseAttachmentPoint = -1;
	private ScrollBarListener listener = null;
	
	public interface ScrollBarListener
	{
		void onChanged(ScrollBarWidget sender, int oldValue, int newValue);
	}
	
	public ScrollBarWidget(Widget parent, Rectangle area)
	{
		this(parent, null, area);
	}
	
	public ScrollBarWidget(Widget parent, ScrollBarListener listener, Rectangle area)
	{
		super(parent, area);
		maxValue = area.height;
		this.listener = listener;
		recalculateBar();
	}
	
	public int getMaxValue()
	{
		return maxValue;
	}
	
	public int getPageSize()
	{
		return pageSize;
	}
	
	public int getValue()
	{
		return currentValue*maxValue/getHeight();
	}
	
	public void setMaximumValue(int newValue)
	{
		if(maxValue != newValue)
		{
			maxValue = newValue;
			recalculateBar();
		}
	}
	
	private void recalculateBar()
	{
		currentValue = 0;
		if(maxValue >= getHeight())
		{
			// find the page size
			double proportion = (double)maxValue / (double)getHeight();
			pageSize = (int)((double)getHeight()/proportion);
		}
		else
		{
			pageSize = getHeight();
		}
	}
	
	private void pageUp()
	{
		setMarkerPosition(currentValue-pageSize);
	}
	
	private void pageDown()
	{
		setMarkerPosition(currentValue + pageSize);
	}
	
	private void setMarkerPosition(int newPos)
	{
		int oldValue = currentValue;
		if(newPos < 0)
		{
			currentValue = 0;
		}
		else
		if(newPos >getHeight()-pageSize)
		{
			currentValue = getHeight()-pageSize;
		}
		else
		{
			currentValue = newPos;
		}
		if(listener != null && oldValue != currentValue)
		{
			listener.onChanged(this, oldValue, currentValue);
		}
	}

	public void paint(Graphics g)
	{
		// fill background
		g.setColor(getTheme().getUIBackgroundColor());
		g.fillRect(0, 0, getWidth()-1, getHeight()-1);
		// draw border
		g.setColor(getTheme().getDefaultBorderColor());
		g.drawRect(0, 0, getWidth()-1, getHeight()-1);
		// draw page
		getTheme().fillUIBackground(g, new Rectangle(0, currentValue, getWidth(), pageSize));
	}

	public void mouseDown(Point pos)
	{
		super.mouseDown(pos);
		// is is above, below, or inside the slider?
		Rectangle slider = new Rectangle(0,currentValue, getWidth(), pageSize);
		if(slider.contains(pos)) // inside
		{
			mouseCapture();
			mouseAttachmentPoint = pos.y - currentValue;
		}
		else
		if(pos.y < currentValue) // above
		{
			pageUp();
		}
		else // below
		{
			pageDown();
		}
	}

	public void mouseUp(Point pos)
	{
		super.mouseUp(pos);
		mouseRelease();
		mouseAttachmentPoint = -1;
	}

	public void mouseMoved(Point point)
	{
		super.mouseMoved(point);
		if(mouseAttachmentPoint != -1)
		{
			setMarkerPosition(point.y - mouseAttachmentPoint );
		}
	}
}
